home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / comm / ums / UMS11_9_beta.lha / UMS / rexx / ReplyDaemon.rexx < prev    next >
OS/2 REXX Batch file  |  1998-08-23  |  11KB  |  314 lines

  1. /* ------------------------------------------------------------------------
  2. :Program.    ReplyDaemon.rexx
  3. :Contents.   send receipt-reply messages depending on folder
  4. :Author.     hartmut Goebel [hG]
  5. :Address.    Aufsesßplatz 5, D-90459 Nürnberg
  6. :Address.    UseNet: hartmut@oberon.nbg.sub.org
  7. :History.    1.0  [hG] initial release
  8. :History.    1.1  [hG] · output onl if there are messages to process
  9. :History.              · no longer tests PostPone flag
  10. :History.    1.2  [hG] uses hgrexxsupport.library 1.2
  11. :History.    2.0  [hG] added optional check for ToName, adapted to UMS v11
  12. :History     2.1  [andre] adapted to UMS v11
  13. :Version.    $VER: ReplyDaemon.rexx 2.1 (23.08.98)
  14. :Copyright.  Public Domain
  15. :Language.   ARexx
  16. :Translator. RexxMast
  17. ------------------------------------------------------------------------ */
  18. /*
  19.  
  20. NAME
  21.      ReplyDaemon  --  send receipt-reply messages depending on folder
  22.  
  23. TEMPLATE
  24.      Name,Password,Server/K,UseReplyAccount/S,UseFolderAsReplyName/S
  25.  
  26. FUNCTION
  27.      ReplyDaemon checks for new messages within some given folders
  28.      and sends receipt-reply messages to the sender of these
  29.      messages. The checked messages will be marked as unread,
  30.      archived and postponed, thus both avoiding re-processing and
  31.      expiring.
  32.  
  33.      This is quite usefull for maintaining e.g. a bugs database where
  34.      the reporters should be given a receipt. You may use a tool like
  35.      Reciever2Folder to sort your messages into folders first and
  36.      then run ReplyDaemon to send the receipt-replies.
  37.  
  38.      The folders to be checked have to be listed in a config
  39.      variable. Also subject and body text for the message to be send
  40.      can be defined per folder via config vars.
  41.  
  42.      The receipt-reply may either be send from the users account or a
  43.      special ReplyDaemon account. The later is for avoiding garbage
  44.      messages in the user's mail folders.
  45.  
  46.      The Reply-Name put in the send message may get three values:
  47.      - the folder name (if option UseFolderAsReplyName is set)
  48.      - a reply name specified by a config var (see below)
  49.      - not set, thus later replies will get to either the user or the
  50.        ReplyDaemon, depenting on the option UsereplyAccount
  51.  
  52. OPTIONS
  53.      Name, Password, Server
  54.         are the normal UMS parameters
  55.  
  56.      UseReplyAccount
  57.         This option tells ReplyDaemon to send the messages not from
  58.         the users account but his own one. Thus it's possible to
  59.         expire the sent replies as soon as they are exported by
  60.         setting 'expire.mail = 0' the the ReplyDaeomn's account.
  61.  
  62.         The ReplyDaeomn's account must have an alias 'ReplyDaemon'
  63.         and require an empty password. Also WriteAccess must be set
  64.         correctly.
  65.  
  66.      UseFolderAsReplyName
  67.          This tells ReplyDaemon to set the ReplyName of send messages
  68.          to the name of the folder. The config-var
  69.          ReplyDaemon.ReplyName.<folder> will not be used then.
  70.  
  71. USED CONFIG-VARS
  72.  
  73.      ReplyDaemon.Folderlist          (required)
  74.           List of folders to be checked, form: FolderName [ "," ToName ]
  75.  
  76.           When specify an optional 'ToName' (seperated from the
  77.           folder name by a comma), only messages addressed to this
  78.           name are replied. Thus you can but all mail about a certain
  79.           project in one single folder and only the bugs get a
  80.           automatic reply.
  81.  
  82.      ReplyDaemon.Subject.<folder>    (required)
  83.      ReplyDaemon.MsgText.<folder>    (required)
  84.           Defines the subject and body text for the send-out message.
  85.           The body text will become preceded by an address ('Hi
  86.           <FromName>') plus one empty line and appended by one emtpy
  87.           line plus the text 'Of course, this message has been
  88.           generated automaticly :-)'.
  89.  
  90.      ReplyDaemon.ReplyName.<folder>  (optional)
  91.           If the option UseFolderAsReplyName is not set, this var
  92.           determines a ReplyName to be put into the send message.
  93.  
  94. EXAMPLE
  95.  
  96.      User
  97.         Name  "Mail-Daemon"
  98.        Alias "Reply-Daemon"
  99.        Password
  100.        NetAccess       = "#?"
  101.        expire.mail     = "0"
  102.        expire.private  = "0"
  103.        .... EndUser
  104.  
  105.      User
  106.        Name  "Joe User"
  107.        Password "noone"
  108.        Alias "ju"
  109.        Alias "project"
  110.        Alias "project-bugs"
  111.        Alias "info"
  112.        ....
  113.        ReplyDaemon.FolderList= "project, project-bugs*ninfo"
  114.        ReplyDaemon.ReplyName.Bugs = "ju"
  115.        ReplyDaemon.Subject.Bugs = "Recieved your bug report:"
  116.        ReplyDaemon.MsgText.Bugs= "Thank you for your bug report.*n
  117.                                   Joe User*NBugs Maintainer" ....
  118.        ReplyDaemon.Subject.Info = "Here's your Info"
  119.        ReplyDaemon.MsgText.Info= "Thank you for requesting the info*n
  120.                                   Joe User" ....
  121.      EndUser
  122.  
  123. TODO
  124.  
  125.  >* Es sollte auch die Möglichkeit geben, statt des Textes direkt (in
  126.  >  ums.config) einen FileNamen für ein Textfile anzugeben (z.B. statt
  127.  >  *.msgtext.* *.msgfile.*). Das bläht die config nicht garso
  128.  >  (unnötig) auf. Die Idee kam mir deshalb, weil man z.B. auf diese
  129.  >  Art ziemlich einfach längere (Info-)Files verschicken könnte, ohne
  130.  >  sie nach jeder Änderung zusätzlich in die ums.config quetschen zu
  131.  >  müssen. Ein schönes Beispiel wäre (dachte ich mir), den PGP public
  132.  >  key automatisiert zu verschicken, wenn jemand an
  133.  >  pgp@irgendwer.nbg.sub.org schreibt.
  134.  
  135. */
  136.  
  137. /*** Init ***/
  138.  
  139. call addlib("rexxdossupport.library", 0, -30)
  140. call addlib("ums.library", 0, -210, 11)
  141. call UMSInitConsts()
  142.  
  143. /*** Startup ***/
  144.  
  145. ProgramName = "ReplyDaemon";
  146. ArgsTemplate = "Name,Password,Server/K,UseReplyAccount/S,UseFolderAsReplyName/S"
  147. ReplyName = "Reply-Daemon";
  148. ReplyPassword = "";
  149.  
  150. /*** Login ***/
  151.  
  152. replyAccount = 0;
  153.  
  154. account = UMSLogin(name, password, server)
  155. if (account = 0) then do
  156.   say "unable to login."
  157.   exit 10
  158. end
  159.  
  160. if useReplyAccount then do
  161.   replyAccount = UMSLogin(replyName, ReplyPassword, server)
  162.   if (replyAccount = 0) then do
  163.     say "unable to login."
  164.     halt 10
  165.   end
  166. end; else
  167.   replyAccount = account
  168.  
  169. FLAGS_Empty = MakeFlags()
  170. FLAG_0 = MakeFlags(0)
  171. FLAG_1 = MakeFlags(1)
  172. FLAG_2 = MakeFlags(2)
  173. FLAGS_012 = MakeFlags(0,1,2)
  174. FLAG_Old = MakeFlags(UMSUSTAT_Old)
  175. FLAGS_PostArch = MakeFlags(UMSUSTAT_PostPoned,UMSUSTAT_Archive)
  176. Match = MakeFlags(UMSUSTAT_ViewAccess)
  177. Mask  = MakeFlags(UMSUSTAT_ViewAccess,/*UMSUSTAT_PostPoned,*/UMSUSTAT_Archive, UMSUSTAT_Old)
  178.  
  179. call UMSSelectField(account, "L", FLAG_0, FLAGS_Empty,,,UMSCODE_Group, "", TRUE)
  180. call UMSSelectFlags(account, "L", FLAG_1, FLAGS_Empty,,,"U", Mask, Match)
  181.  
  182. Folderlist = GetUMSConfigVar("","Folderlist", TRUE)
  183. do forever
  184.   parse var FolderList FolderName '0A'x Folderlist
  185.   FolderName = strip(FolderName)
  186.   if FolderName = '' then leave;
  187.   parse var FolderName FolderName ',' ToName
  188.   ToName = upper(ToName);
  189.   call ReplyOnMsgsInFolder;
  190. end
  191.  
  192. /*** Final cleanup ***/
  193.  
  194. BREAK_C:
  195. BREAK_D:
  196. BREAK_E:
  197. BREAK_F:
  198. ERROR:
  199. HALT:
  200. IOERR:
  201. SYNTAX:
  202.  
  203. IF RC ~= 0 THEN DO
  204.   say "Error: " rc errortext(rc) "Line" sigl
  205. END
  206.  
  207. /*** Logout ***/
  208.  
  209. call UMSLogout(account)
  210. if useReplyAccount then
  211.   call UMSLogout(replyAccount)
  212. exit
  213.  
  214. ReplyOnMsgsInFolder:
  215.   MessageText = GetUMSConfigVar(FolderName,"MsgText", TRUE)
  216.   Subject     = GetUMSConfigVar(FolderName,"Subject", TRUE)
  217.   ReplyName   = GetUMSConfigVar(FolderName,"ReplyName", FALSE)
  218.  
  219.   call UMSSelectFlags(account, "L", FLAGS_Empty, FLAG_2,,,"U", FLAGS_Empty, FLAGS_Empty)
  220.   call UMSSelectField(account, "L", FLAG_2, FLAGS_Empty,,,UMSCODE_Folder, FolderName)
  221.  
  222.   numTagedMsgs = UMSSelectFlags(account, "L", FLAGS_Empty, FLAGS_Empty,,,"L", FLAGS_012, FLAGS_012)
  223.  
  224.   if numTagedMsgs = 0 then return
  225.  
  226.   say ProgramName || ":" numTagedMsgs "messages in folder" FolderName "found"
  227.   i=0;last = 0
  228.   do forever
  229.     last = UMSSearchFlags(account, "L", FLAGS_012, FLAGS_012, last)
  230.     if last = 0 then leave /* we are done */
  231.  
  232.     drop msg. /* _IMPORTANT_ */
  233.     if ~ UMSReadMsgHeader(account, last, msg.,true) then do
  234.       call CheckErr
  235.       exit
  236.     end
  237.  
  238.     /* generate reply */
  239.     drop newmsg.
  240.     if symbol("msg.UMSCODE_ReplyName") = "VAR" then do
  241.       newmsg.UMSCODE_ToName = msg.UMSCODE_ReplyName
  242.     end; else
  243.       newmsg.UMSCODE_ToName = msg.UMSCODE_FromName
  244.  
  245.     /* test whether we should not reply */
  246.     if (find(msg.UMSCODE_Attributes,'receipt') ~= 0),  /* genaratec message */
  247.     | abbrev(upper(newmsg.UMSCODE_ToName),"MAILINGLIST "),  /* no reply to a mailinglist */
  248.     | ((ToName ~= '') & (upper(msg.UMSCODE_ToName) ~= ToName))
  249.     then
  250.       iterate
  251.  
  252.     if symbol("msg.UMSCODE_ReplyAddr") = "VAR" then do
  253.       newmsg.UMSCODE_ToAddr = msg.UMSCODE_ReplyAddr
  254.     end; else if symbol("msg.UMSCODE_FromAddr") = "VAR" then do
  255.       newmsg.UMSCODE_ToAddr = msg.UMSCODE_FromAddr
  256.     end
  257.     if useFolderAsReplyName then do
  258.       newmsg.UMSCODE_ReplyName = FolderName;
  259.     end; else if ReplyName ~= "" then do
  260.       newmsg.UMSCODE_ReplyName = ReplyName;
  261.     end
  262.     newmsg.UMSCODE_RefID   = msg.UMSCODE_MsgID
  263.     newmsg.UMSCODE_Attributes = "receipt"
  264.     newmsg.UMSCODE_Subject = Subject msg.UMSCODE_Subject
  265.     newmsg.UMSCODE_MsgText = "Hi" msg.UMSCODE_FromName ||"!" || '0A 0A'x || MessageText ||,
  266.     '0A 0A'x || 'Of course, this message has been generated automaticly :-)'
  267.  
  268.     if UMSWriteMsg(replyAccount, newmsg.) = 0 then
  269.       call CheckErr
  270.     else do
  271.       /* mark message as postponed and archived but unread */
  272.       call UMSSelectMsg(account,"U", FLAGS_PostArch, FLAG_Old, last)
  273.       i = i+1;
  274.     end;
  275.   end;
  276.   say i
  277.   return;
  278.  
  279. GetUMSConfigVar: procedure expose account replyAccount programname useReplyAccount
  280.   /* search order:
  281.    * User:  ProgName.varname.FolderName
  282.    * User:  ProgName.varname
  283.    * ReplyDeamon ProgName.varname
  284.    */
  285.   FolderName = arg(1);
  286.   if FolderName ~= '' then
  287.     Foldername = '.'FolderName;
  288.   varname = ProgramName || "."arg(2);
  289.   var = UMSReadConfig(account,varname || FolderName)
  290.   if (var = "") & (FolderName ~= "") then
  291.     var = UMSReadConfig(account,varname)
  292.   if (var = "") & useReplyAccount & (replyAccount ~= 0) then
  293.     var = UMSReadConfig(replyAccount,varname)
  294.   if (arg(3) = TRUE) then do
  295.     if (var = '') then do
  296.       say ProgramName || ": Configuration variable '" || varname || "' is missing!"
  297.       exit
  298.     end
  299.   end
  300.   return var
  301.  
  302. /*** Support ***/
  303.  
  304. CheckErr: procedure expose account replyAccount useReplyAccount
  305.   err = UMSErrNum(account)
  306.   if err ~= 0 then do
  307.     say "UMS Error #" || err || ": " || UMSErrTxt(account)
  308.   end; else if useReplyAccount then do
  309.     err = UMSErrNum(replyAccount)
  310.     if err ~= 0 then
  311.     say "UMS Error #" || err || ": " || UMSErrTxt(replyAccount)
  312.   end
  313. return
  314.